package com.hy.service.impl;

import com.hy.service.ConversationHistoryService;
import com.hy.service.IntentRecognitionService;
import com.hy.service.LlmService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class IntentRecognitionServiceImpl implements IntentRecognitionService {

    private static final String INDUSTRY_DATA = "your_industry_data";
    private static final Map<String, String> DETAIL_DATA = new HashMap<>();

    static {
        // 初始化 DETAIL_DATA
    }

    @Autowired
    private LlmService llmService;

    @Autowired
    private ConversationHistoryService conversationHistoryService;

    public String processQuestion(String question) {
        // 根据上下文完善问题
        question = removeEndToken(getFullContext(question));

        // 记录用户提问
        conversationHistoryService.addQuestion(question);

        // 大类识别
        String generalIntent = removeEndToken(recognizeGeneralIntent(question));

        // 细则处理
        String detail = "未找到具体办理事项";
        for (String category : generalIntent.split(";")) {
            if (checkItemInList(category)) {
                detail = removeEndToken(recognizeDetailIntent(question, category));
                if (!"未识别到相关类别".equals(detail) && !"未识别到相关类别;".equals(detail)) {
                    break;
                }
            }
        }

        // 优化意图
        // String optimizedResult = removeEndToken(optimizeIntent(question, detail));

        return detail;
    }

    private String getFullContext(String question) {
        String context = conversationHistoryService.getRecentHistory();
        String instruction = """
                你是一个政务服务中心智能客服，拥有丰富的政务知识和良好的逻辑分析能力。你擅长根据用户问题，给出具体的办理流程。

                政务服务事项包括行政权力事项和公共服务事项。行政权力事项,包括行政许可、行政给付、行政确认、行政裁决等依申请实施的事项,以及为申请人履行法定义务提供便利的事项。本条例所称公共服务事项,包括利用公共资源提供的教育、医疗卫生、社会保障、劳动就业、住房保障、文化体育、救助帮扶、法律服务等与日常生产生活密切相关的服务事项,以及服务创新创业需求的综合服务事项。

                只输出最相关且经过完善的问题，禁止输出其他任何内容。
                """;
        try {
            return llmService.callLlm(instruction, question);
        } catch (Exception e) {
            System.err.println("调用 LLM 时出错: " + e.getMessage());
            return question;
        }
    }

    private String recognizeGeneralIntent(String question) {
        String instruction = """
                ### 角色定义：
                你是一位经验丰富的政务服务中心的用户意图识别专家，熟悉政务服务中心覆盖的全领域业务，能快速精准定位用户需求，依据分类标准筛选出最相关的政务行业类别。

                ### 核心任务：
                深度剖析用户问题，不仅要捕捉显性需求，还要挖掘潜在关联业务，从分类标准中找出一个最相关的类别。

                ### 分类标准：
                """ + INDUSTRY_DATA + """

                ### 输出规则：
                严格遵循预设分类标准，禁止生成标准外的类别。
                必须包含所有匹配项，多行业用';'连接。
                仅输出行业标签，禁止附加解释或序号。
                如果匹配不到分类标准中的类别，输出"未识别到相关行业"
                """;
        try {
            return llmService.callLlm(instruction, question);
        } catch (Exception e) {
            System.err.println("调用 LLM 时出错: " + e.getMessage());
            return "未识别到相关行业";
        }
    }

    private String recognizeDetailIntent(String question, String generalIntent) {
        String detail = DETAIL_DATA.getOrDefault(generalIntent, "");
        if (detail.isEmpty()) {
            return "未识别到相关类别";
        }
        String instruction = """
                ### 角色定义：
                你是一位政务服务中心意图分析大师，对所有业务流程了如指掌。
                已知用户的问题与""" + detail +
                """
                        行业相关，你需要从分类标准中的""" + detail + """
                行业的所有业务中，找到用户所有可能需要办理的业务。

                ### 核心任务:
                1. 精准分析问题中的核心动词（开办/变更/注销等）和主体（企业/个体户等），明确用户的具体操作和涉及对象。
                2. 准确识别涉及的行政领域（工商/卫生/税务等），确定业务所属的行政范畴。
                3. 匹配行业分类时优先考虑：
                - 直接匹配：优先匹配问题中明确提到的行业名称。
                - 间接匹配：若没有直接匹配项，根据业务特性进行合理推导。
                - 关联匹配：若前两者都不满足，考虑上下游相关业务。

                ### 分类标准：
                """ + detail + """

                ### 匹配规则：
                优先保留用户直接提及的行业名称对应的业务
                若没有明确行业名称，保留业务流程中关键的许可事项
                若没有核心许可事项，保留相关的备案事项
                最后考虑公共服务事项

                ### 示例：
                开店就必须办理营业执照，行业准入资格，公共场所卫生许可和公众聚集场所投入使用、营业前消防安全检查四项业务。

                ### 输出规则：
                严格遵循预设分类标准，禁止生成标准类别外的任何内容。
                禁止重复输出。
                必须包含所有匹配项，多类别用';'连接。
                仅输出行业标签，禁止附加解释或序号。
                如果匹配不到分类标准中的类别，输出"未识别到相关类别"
                """;
        try {
            return llmService.callLlm(instruction, question);
        } catch (Exception e) {
            System.err.println("调用 LLM 时出错: " + e.getMessage());
            return "未识别到相关类别";
        }
    }

    private String optimizeIntent(String question, String result) {
        String instruction = """
                ### 角色定义：
                你是一个政务中心的智能判别专家，能够根据用户的问题，运用专业知识和逻辑判断，精准筛选出已选择业务中与用户问题最相关的业务。

                ### 已选定的事项为：
                """ + result + """

                ### 匹配规则
                优先保留用户直接提及的行业名称对应的业务
                若没有明确行业名称，保留业务流程中关键的许可事项
                若没有核心许可事项，保留相关的备案事项
                最后考虑公共服务事项

                ### 输出规则：
                只能输出业务名称，禁止输出其他内容。
                必须包含所有匹配项，多行业用';'连接。
                """;
        try {
            return llmService.callLlm(instruction, question);
        } catch (Exception e) {
            System.err.println("调用 LLM 时出错: " + e.getMessage());
            return result;
        }
    }

    private boolean checkItemInList(String item) {
        Set<String> industrySet = INDUSTRY_DATA.chars()
                .mapToObj(c -> String.valueOf((char) c))
                .collect(Collectors.toSet());
        return industrySet.contains(item);
    }

    private String removeEndToken(String text) {
        return text.replace("<|im_end|>", "").trim();
    }
}
